package com.winexpress.session.sr;

import com.winexpress.entity.Category;
import com.winexpress.entity.OrderHistory;
import com.winexpress.entity.OrderLine;
import com.winexpress.entity.SalesReport;
import com.winexpress.entity.Wine;
import com.winexpress.session.product.ProductSessionBean;
import static com.winexpress.session.sr.UrlInfo.makeRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.SignatureException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.LocalBean;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

@Stateless
@LocalBean
public class SalesReportSessionBean {

    @PersistenceContext
    private EntityManager em;

    @EJB
    private ProductSessionBean productSessionBean;

    public List<SalesReport> listSalesYear() {
        Query q = em.createQuery("SELECT o FROM OrderHistory o");
        List<OrderHistory> allOrderHistory = q.getResultList();
        double y2014s = 0;
        double y2014p = 0;
        double y2013s = 0;
        double y2013p = 0;
        double y2012s = 0;
        double y2012p = 0;

        for (OrderHistory history : allOrderHistory) {
            String info = String.valueOf(history.getDate());
            //     System.out.println(info);
            String yearInfo = info.substring(24, 28);
            //  System.out.println(yearInfo);

            List<OrderLine> allLines = history.getOrderLines();
            if (yearInfo.equals("2014")) {
                for (OrderLine line : allLines) {
                    y2014s += line.getPrice() * line.getQuantity() * (1 - line.getDiscount() / 100);
                    y2014p += (line.getPrice() * (1 - line.getDiscount() / 100) - line.getCost()) * line.getQuantity();
                }
            } else if (yearInfo.equals("2013")) {
                for (OrderLine line : allLines) {
                    y2013s += line.getPrice() * line.getQuantity() * (1 - line.getDiscount() / 100);
                    y2013p += (line.getPrice() * (1 - line.getDiscount() / 100) - line.getCost()) * line.getQuantity();
                }
            } else if (yearInfo.equals("2012")) {
                for (OrderLine line : allLines) {
                    y2012s += line.getPrice() * line.getQuantity() * (1 - line.getDiscount() / 100);
                    y2012p += (line.getPrice() * (1 - line.getDiscount() / 100) - line.getCost()) * line.getQuantity();
                }
            }
        }
        List<SalesReport> list = new ArrayList<SalesReport>();
        SalesReport r2014 = new SalesReport();
        r2014.setYr("2014");
        r2014.setSales(y2014s);
        r2014.setProfit(y2014p);
        list.add(r2014);

        SalesReport r2013 = new SalesReport();
        r2013.setYr("2013");
        r2013.setSales(y2013s);
        r2013.setProfit(y2013p);
        list.add(r2013);

        SalesReport r2012 = new SalesReport();
        r2012.setYr("2012");
        r2012.setSales(y2012s);
        r2012.setProfit(y2012p);
        list.add(r2012);
        //   System.out.println(list.get(1).getSales());
        return list;
    }

    public List<SalesReport> salesByYear(String yr) throws ParseException {
        double m1s = 0;
        double m1p = 0;
        double m2s = 0;
        double m2p = 0;
        double m3s = 0;
        double m3p = 0;
        double m4s = 0;
        double m4p = 0;
        double m5s = 0;
        double m5p = 0;
        double m6s = 0;
        double m6p = 0;
        double m7s = 0;
        double m7p = 0;
        double m8s = 0;
        double m8p = 0;
        double m9s = 0;
        double m9p = 0;
        double m10s = 0;
        double m10p = 0;
        double m11s = 0;
        double m11p = 0;
        double m12s = 0;
        double m12p = 0;

        String startstr = "January 1, " + yr;
        String endstr = "December 31, " + yr;
        Date startdate = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH).parse(startstr);
        Date enddate = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH).parse(endstr);
        Query q = em.createQuery("SELECT o FROM OrderHistory o WHERE o.date BETWEEN :start AND :end");
        q.setParameter("start", startdate);
        q.setParameter("end", enddate);
        List<OrderHistory> historyList = q.getResultList();
        for (OrderHistory history : historyList) {
            String info = String.valueOf(history.getDate());
            // System.out.println(info);
            String monthInfo = info.substring(4, 7);
            //    System.out.println(monthInfo);
            List<OrderLine> allLines = history.getOrderLines();
            if (monthInfo.equals("Jan")) {
                for (OrderLine line : allLines) {
                    m1s += line.getPrice() * line.getQuantity() * (1 - line.getDiscount() / 100);
                    m1p += (line.getPrice() * (1 - line.getDiscount() / 100) - line.getCost()) * line.getQuantity();
                }
            } else if (monthInfo.equals("Feb")) {
                for (OrderLine line : allLines) {
                    m2s += line.getPrice() * line.getQuantity() * (1 - line.getDiscount() / 100);
                    m2p += (line.getPrice() * (1 - line.getDiscount() / 100) - line.getCost()) * line.getQuantity();
                }
            } else if (monthInfo.equals("Mar")) {
                for (OrderLine line : allLines) {
                    m3s += line.getPrice() * line.getQuantity() * (1 - line.getDiscount() / 100);
                    m3p += (line.getPrice() * (1 - line.getDiscount() / 100) - line.getCost()) * line.getQuantity();
                }
            } else if (monthInfo.equals("Apr")) {
                for (OrderLine line : allLines) {
                    m4s += line.getPrice() * line.getQuantity() * (1 - line.getDiscount() / 100);
                    m4p += (line.getPrice() * (1 - line.getDiscount() / 100) - line.getCost()) * line.getQuantity();
                }
            } else if (monthInfo.equals("May")) {
                for (OrderLine line : allLines) {
                    m5s += line.getPrice() * line.getQuantity() * (1 - line.getDiscount() / 100);
                    m5p += (line.getPrice() * (1 - line.getDiscount() / 100) - line.getCost()) * line.getQuantity();
                }
            } else if (monthInfo.equals("Jun")) {
                for (OrderLine line : allLines) {
                    m6s += line.getPrice() * line.getQuantity() * (1 - line.getDiscount() / 100);
                    m6p += (line.getPrice() * (1 - line.getDiscount() / 100) - line.getCost()) * line.getQuantity();
                }
            } else if (monthInfo.equals("Jul")) {
                for (OrderLine line : allLines) {
                    m7s += line.getPrice() * line.getQuantity() * (1 - line.getDiscount() / 100);
                    m7p += (line.getPrice() * (1 - line.getDiscount() / 100) - line.getCost()) * line.getQuantity();
                }
            } else if (monthInfo.equals("Aug")) {
                for (OrderLine line : allLines) {
                    m8s += line.getPrice() * line.getQuantity() * (1 - line.getDiscount() / 100);
                    m8p += (line.getPrice() * (1 - line.getDiscount() / 100) - line.getCost()) * line.getQuantity();
                }
            } else if (monthInfo.equals("Sep")) {
                for (OrderLine line : allLines) {
                    m9s += line.getPrice() * line.getQuantity() * (1 - line.getDiscount() / 100);
                    m9p += (line.getPrice() * (1 - line.getDiscount() / 100) - line.getCost()) * line.getQuantity();
                }
            } else if (monthInfo.equals("Oct")) {
                for (OrderLine line : allLines) {
                    m10s += line.getPrice() * line.getQuantity() * (1 - line.getDiscount() / 100);
                    m10p += (line.getPrice() * (1 - line.getDiscount() / 100) - line.getCost()) * line.getQuantity();
                }
            } else if (monthInfo.equals("Nov")) {
                for (OrderLine line : allLines) {
                    m11s += line.getPrice() * line.getQuantity() * (1 - line.getDiscount() / 100);
                    m11p += (line.getPrice() * (1 - line.getDiscount() / 100) - line.getCost()) * line.getQuantity();
                }
            } else if (monthInfo.equals("Dec")) {
                for (OrderLine line : allLines) {
                    m12s += line.getPrice() * line.getQuantity() * (1 - line.getDiscount() / 100);
                    m12p += (line.getPrice() * (1 - line.getDiscount() / 100) - line.getCost()) * line.getQuantity();
                }
            }
        }
        List<SalesReport> list = new ArrayList<SalesReport>();
        SalesReport mon1 = new SalesReport();
        mon1.setMth("1");
        mon1.setSales(m1s);
        mon1.setProfit(m1p);
        list.add(mon1);
        SalesReport mon2 = new SalesReport();
        mon2.setMth("2");
        mon2.setSales(m2s);
        mon2.setProfit(m2p);
        list.add(mon2);
        SalesReport mon3 = new SalesReport();
        mon3.setMth("3");
        mon3.setSales(m3s);
        mon3.setProfit(m3p);
        list.add(mon3);
        SalesReport mon4 = new SalesReport();
        mon4.setMth("4");
        mon4.setSales(m4s);
        mon4.setProfit(m4p);
        list.add(mon4);
        SalesReport mon5 = new SalesReport();
        mon5.setMth("5");
        mon5.setSales(m5s);
        mon5.setProfit(m5p);
        list.add(mon5);
        SalesReport mon6 = new SalesReport();
        mon6.setMth("6");
        mon6.setSales(m6s);
        mon6.setProfit(m6p);
        list.add(mon6);
        SalesReport mon7 = new SalesReport();
        mon7.setMth("7");
        mon7.setSales(m7s);
        mon7.setProfit(m7p);
        list.add(mon7);
        SalesReport mon8 = new SalesReport();
        mon8.setMth("8");
        mon8.setSales(m8s);
        mon8.setProfit(m8p);
        list.add(mon8);
        SalesReport mon9 = new SalesReport();
        mon9.setMth("9");
        mon9.setSales(m9s);
        mon9.setProfit(m9p);
        list.add(mon9);
        SalesReport mon10 = new SalesReport();
        mon10.setMth("10");
        mon10.setSales(m10s);
        mon10.setProfit(m10p);
        list.add(mon10);
        SalesReport mon11 = new SalesReport();
        mon11.setMth("11");
        mon11.setSales(m11s);
        mon11.setProfit(m11p);
        list.add(mon11);
        SalesReport mon12 = new SalesReport();
        mon12.setMth("12");
        mon12.setSales(m12s);
        mon12.setProfit(m12p);
        list.add(mon12);
        return list;
    }

    public SalesReport salesByPeriod(String fromYr, String fromMth, String fromDay, String toYr, String toMth, String toDay) throws ParseException {
        double sales = 0;
        double profit = 0;
        double[] wineSales = new double[1000];
        double[] wineProfit = new double[1000];
        int[] qty = new int[1000];
        String categotyid;
        double[] categorySales;
        double[] categoryProfit;
        SalesReport report = new SalesReport();
        String startstr = fromMth + " " + fromDay + ", " + fromYr;
        String endstr = toMth + " " + toDay + ", " + toYr;
        //     System.out.println(startstr);
        //      System.out.println(endstr);
        Date startdate = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH).parse(startstr);
        Date enddate = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH).parse(endstr);
        //    System.out.println(startdate);
        //    System.out.println(enddate);
        Query q1 = em.createQuery("SELECT w FROM Wine w");
        List<Wine> wineList = q1.getResultList();
        for (Wine eachwine : wineList) {
            int wineId = eachwine.getId().intValue();
            wineSales[wineId] = 0;
            wineProfit[wineId] = 0;
            qty[wineId] = 0;
        }
        Query q = em.createQuery("SELECT o FROM OrderHistory o WHERE o.date BETWEEN :start AND :end");
        q.setParameter("start", startdate);
        q.setParameter("end", enddate);
        List<OrderHistory> historyList = q.getResultList();

        for (OrderHistory history : historyList) {
            List<OrderLine> allLines = history.getOrderLines();
            for (OrderLine line : allLines) {
                sales += line.getPrice() * line.getQuantity() * (1 - line.getDiscount() / 100);
                profit += (line.getPrice() * (1 - line.getDiscount() / 100) - line.getCost()) * line.getQuantity();
                wineSales[line.getWine().getId().intValue()] += line.getPrice() * line.getQuantity() * (1 - line.getDiscount() / 100);
                wineProfit[line.getWine().getId().intValue()] += (line.getPrice() * (1 - line.getDiscount() / 100) - line.getCost()) * line.getQuantity();
                qty[line.getWine().getId().intValue()] += line.getQuantity();
            }
        }
//        for(int i=0;i<wineSales.length;i++){
//            if (wineSales[i]!=0){
//                System.out.println(i);
//                 System.out.println(wineSales[i]);
//            }
//                   
//        }
        report.setWineSales(wineSales);
        report.setWineProfit(wineProfit);
        report.setQty(qty);
        report.setProfit(profit);
        report.setSales(sales);
        return report;
    }

    public SalesReport salesByPeriodProduct(String fromYr, String fromMth, String fromDay, String toYr, String toMth, String toDay, String wineid) throws ParseException {
        double sales = 0;
        double profit = 0;
        int qty = 0;
        Long wine = Long.parseLong(wineid);

        SalesReport report = new SalesReport();
        String startstr = fromMth + " " + fromDay + ", " + fromYr;
        String endstr = toMth + " " + toDay + ", " + toYr;
        //     System.out.println(startstr);
        //      System.out.println(endstr);
        Date startdate = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH).parse(startstr);
        Date enddate = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH).parse(endstr);
        //    System.out.println(startdate);
        //    System.out.println(enddate);

        Query q = em.createQuery("SELECT o FROM OrderHistory o WHERE o.date BETWEEN :start AND :end ");
        q.setParameter("start", startdate);
        q.setParameter("end", enddate);
        List<OrderHistory> historyList = q.getResultList();

        for (OrderHistory history : historyList) {
            List<OrderLine> allLines = history.getOrderLines();
            for (OrderLine line : allLines) {
                if (line.getWine().getId() == wine) {
                    sales += line.getPrice() * line.getQuantity() * (1 - line.getDiscount() / 100);
                    profit += (line.getPrice() * (1 - line.getDiscount() / 100) - line.getCost()) * line.getQuantity();
                    qty += line.getQuantity();
                }
            }
        }
        // System.out.println(qty);
        report.setSingleQty(qty);
        report.setProfit(profit);
        report.setSales(sales);
        return report;
    }

    public SalesReport salesByPeriodCategory(String fromYr, String fromMth, String fromDay, String toYr, String toMth, String toDay, String catid) throws ParseException {
        double sales = 0;
        double profit = 0;
        int qty = 0;
        Long cat = Long.parseLong(catid);

        SalesReport report = new SalesReport();
        String startstr = fromMth + " " + fromDay + ", " + fromYr;
        String endstr = toMth + " " + toDay + ", " + toYr;
        //     System.out.println(startstr);
        //      System.out.println(endstr);
        Date startdate = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH).parse(startstr);
        Date enddate = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH).parse(endstr);
        //    System.out.println(startdate);
        //    System.out.println(enddate);

        Query q = em.createQuery("SELECT o FROM OrderHistory o WHERE o.date BETWEEN :start AND :end ");
        q.setParameter("start", startdate);
        q.setParameter("end", enddate);
        List<OrderHistory> historyList = q.getResultList();
        Category selectedCat = em.find(Category.class, cat);
        for (OrderHistory history : historyList) {
            List<OrderLine> allLines = history.getOrderLines();
            for (OrderLine line : allLines) {
                if (selectedCat.equals(productSessionBean.findCategory(String.valueOf(line.getWine().getId())))) {
                    sales += line.getPrice() * line.getQuantity() * (1 - line.getDiscount() / 100);
                    profit += (line.getPrice() * (1 - line.getDiscount() / 100) - line.getCost()) * line.getQuantity();
                    qty += line.getQuantity();
                }
            }
        }
        // System.out.println(qty);
        report.setSingleQty(qty);
        report.setProfit(profit);
        report.setSales(sales);
        return report;
    }

    public SalesReport Awis() throws UnsupportedEncodingException, SignatureException, IOException {
        String SERVICE_HOST = "awis.amazonaws.com";
        String AWS_BASE_URL = "http://" + SERVICE_HOST + "/?";

        String accessKey = "AKIAIA7ST2KLHXL7VV5A";
        String secretKey = "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";
        String site = "https://www.winexpress6.tk";
       //         String site = "http://www.google.com";
        ;
        UrlInfo urlInfo = new UrlInfo(accessKey, secretKey, site);

        String query = urlInfo.buildQuery();

        String toSign = "GET\n" + SERVICE_HOST + "\n/\n" + query;

        System.out.println(
                "String to sign:\n" + toSign + "\n");

        String signature = urlInfo.generateSignature(toSign);

        String uri = AWS_BASE_URL + query + "&Signature="
                + URLEncoder.encode(signature, "UTF-8");

        System.out.println(
                "Making request to:\n");
        System.out.println(uri
                + "\n");

        String title = "Unavialable";
        String MedianLoadTime = "Unavailable";
        String Percentile = "Unavialable";
        String Rank ="Unavialable";
        String RankByCountry="Unavialable";
        String UsageStatistics="Unavialable";
        String ContributingSubdomains="Unavialable";
        // Make the Request
        String xmlResponse = makeRequest(uri);
        System.out.println(xmlResponse);
        if (!xmlResponse.contains("<aws:Title/>")) {
            title = xmlResponse.substring(xmlResponse.indexOf("<aws:Title>") + 11, xmlResponse.indexOf("</aws:Title>"));
        }
        if (!xmlResponse.contains("<aws:MedianLoadTime/>")) {
            MedianLoadTime = xmlResponse.substring(xmlResponse.indexOf("<aws:MedianLoadTime>") + 20, xmlResponse.indexOf("</aws:MedianLoadTime>"));
        }
        if (!xmlResponse.contains("<aws:Percentile/>")) {
            Percentile = xmlResponse.substring(xmlResponse.indexOf("<aws:Percentile>") + 16, xmlResponse.indexOf("</aws:Percentile>"));
        }
        if (!xmlResponse.contains("<aws:Rank/>")) {
            Rank = xmlResponse.substring(xmlResponse.indexOf("<aws:Rank>") + 10, xmlResponse.indexOf("</aws:Rank>"));
        }
        if (!xmlResponse.contains("<aws:RankByCountry/>")) {
            RankByCountry = xmlResponse.substring(xmlResponse.indexOf("<aws:RankByCountry>") + 19, xmlResponse.indexOf("</aws:RankByCountry>"));
        }
        if (!xmlResponse.contains("<aws:UsageStatistics/>")) {
            UsageStatistics = xmlResponse.substring(xmlResponse.indexOf("<aws:UsageStatistics>") + 21, xmlResponse.indexOf("</aws:UsageStatistics>"));
        }
        if (!xmlResponse.contains("<aws:ContributingSubdomains/>")) {
            ContributingSubdomains = xmlResponse.substring(xmlResponse.indexOf("<aws:ContributingSubdomains>") + 28, xmlResponse.indexOf("</aws:ContributingSubdomains>"));
        }

        SalesReport report = new SalesReport();
        
        report.setTitle(title);
        report.setMedianLoadTime(MedianLoadTime);
        report.setPercentile(Percentile);
        report.setRank(Rank);
        report.setRankByCountry(RankByCountry);
        report.setUsageStatistics(UsageStatistics);
        report.setContributingSubdomains(ContributingSubdomains);
        return report;
    }
}
